home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / flex_2_3 / part03 < prev    next >
Encoding:
Internet Message Format  |  1990-08-19  |  61.2 KB

  1. Path: abcfd20.larc.nasa.gov!amiga-request
  2. From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v90i230: flex 2.3 - fast lexical analyzer generator, Part03/13
  4. Reply-To: loftus@wpllabs.uucp (William P Loftus)
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v90i230@abcfd20.larc.nasa.gov>
  7. Date: 19 Aug 90 22:42:16 GMT
  8. Approved: tadguy@uunet.UU.NET (Tad Guy)
  9. X-Mail-Submissions-To: amiga@uunet.uu.net
  10. X-Post-Discussions-To: comp.sys.amiga
  11.  
  12. Submitted-by: loftus@wpllabs.uucp (William P Loftus)
  13. Posting-number: Volume 90, Issue 230
  14. Archive-name: unix/flex-2.3/part03
  15.  
  16. #!/bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 3 (of 13)."
  23. # Contents:  flex.skel main.c nfa.c
  24. # Wrapped by tadguy@abcfd20 on Sun Aug 19 18:41:42 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'flex.skel' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'flex.skel'\"
  28. else
  29. echo shar: Extracting \"'flex.skel'\" \(19618 characters\)
  30. sed "s/^X//" >'flex.skel' <<'END_OF_FILE'
  31. X/* A lexical scanner generated by flex */
  32. X
  33. X/* scanner skeleton version:
  34. X * $Header: WPL:Generators/flex-2.3/RCS/flex.skel,v 1.2 90/07/15 01:17:26 loftus Exp $
  35. X */
  36. X
  37. X#define FLEX_SCANNER
  38. X
  39. X#include <stdio.h>
  40. X
  41. X#ifdef __STDC__
  42. X
  43. X#ifndef DONT_HAVE_STDLIB_H
  44. X#include <stdlib.h>
  45. X#else
  46. Xvoid *malloc( unsigned );
  47. Xvoid free( void* );
  48. X#endif
  49. X
  50. X#define YY_USE_PROTOS
  51. X#define YY_USE_CONST
  52. X#endif
  53. X
  54. X
  55. X/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
  56. X#ifdef c_plusplus
  57. X#ifndef __cplusplus
  58. X#define __cplusplus
  59. X#endif
  60. X#endif
  61. X
  62. X
  63. X#ifdef __cplusplus
  64. X
  65. X#ifndef __STDC__
  66. X#include <stdlib.h>
  67. X#endif
  68. X
  69. X#include <osfcn.h>
  70. X
  71. X/* use prototypes in function declarations */
  72. X#define YY_USE_PROTOS
  73. X
  74. X/* the "const" storage-class-modifier is valid */
  75. X#define YY_USE_CONST
  76. X
  77. X#endif
  78. X
  79. X
  80. X#ifdef __TURBOC__
  81. X#define YY_USE_CONST
  82. X#endif
  83. X
  84. X
  85. X#ifndef YY_USE_CONST
  86. X#define const
  87. X#endif
  88. X
  89. X
  90. X#ifdef YY_USE_PROTOS
  91. X#define YY_PROTO(proto) proto
  92. X#else
  93. X#define YY_PROTO(proto) ()
  94. X/* there's no standard place to get these definitions */
  95. Xchar *malloc();
  96. Xint free();
  97. Xint read();
  98. X#endif
  99. X
  100. X
  101. X/* amount of stuff to slurp up with each read */
  102. X#ifndef YY_READ_BUF_SIZE
  103. X#define YY_READ_BUF_SIZE 8192
  104. X#endif
  105. X
  106. X/* returned upon end-of-file */
  107. X#define YY_END_TOK 0
  108. X
  109. X/* copy whatever the last rule matched to the standard output */
  110. X
  111. X/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */
  112. X/* this used to be an fputs(), but since the string might contain NUL's,
  113. X * we now use fwrite()
  114. X */
  115. X#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout )
  116. X
  117. X/* gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
  118. X * is returned in "result".
  119. X */
  120. X#define YY_INPUT(buf,result,max_size) \
  121. X    if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
  122. X        YY_FATAL_ERROR( "read() in flex scanner failed" );
  123. X#define YY_NULL 0
  124. X
  125. X/* no semi-colon after return; correct usage is to write "yyterminate();" -
  126. X * we don't want an extra ';' after the "return" because that will cause
  127. X * some compilers to complain about unreachable statements.
  128. X */
  129. X#define yyterminate() return ( YY_NULL )
  130. X
  131. X/* report a fatal error */
  132. X
  133. X/* The funky do-while is used to turn this macro definition into
  134. X * a single C statement (which needs a semi-colon terminator).
  135. X * This avoids problems with code like:
  136. X *
  137. X *     if ( something_happens )
  138. X *        YY_FATAL_ERROR( "oops, the something happened" );
  139. X *    else
  140. X *        everything_okay();
  141. X *
  142. X * Prior to using the do-while the compiler would get upset at the
  143. X * "else" because it interpreted the "if" statement as being all
  144. X * done when it reached the ';' after the YY_FATAL_ERROR() call.
  145. X */
  146. X
  147. X#define YY_FATAL_ERROR(msg) \
  148. X    do \
  149. X        { \
  150. X        (void) fputs( msg, stderr ); \
  151. X        (void) putc( '\n', stderr ); \
  152. X        exit( 1 ); \
  153. X        } \
  154. X    while ( 0 )
  155. X
  156. X/* default yywrap function - always treat EOF as an EOF */
  157. X#define yywrap() 1
  158. X
  159. X/* enter a start condition.  This macro really ought to take a parameter,
  160. X * but we do it the disgusting crufty way forced on us by the ()-less
  161. X * definition of BEGIN
  162. X */
  163. X#define BEGIN yy_start = 1 + 2 *
  164. X
  165. X/* action number for EOF rule of a given start state */
  166. X#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
  167. X
  168. X/* special action meaning "start processing a new file" */
  169. X#define YY_NEW_FILE \
  170. X    do \
  171. X        { \
  172. X        yy_init_buffer( yy_current_buffer, yyin ); \
  173. X        yy_load_buffer_state(); \
  174. X        } \
  175. X    while ( 0 )
  176. X
  177. X/* default declaration of generated scanner - a define so the user can
  178. X * easily add parameters
  179. X */
  180. X#define YY_DECL int yylex YY_PROTO(( void )) 
  181. X
  182. X/* code executed at the end of each rule */
  183. X#define YY_BREAK break;
  184. X
  185. X#define YY_END_OF_BUFFER_CHAR 0
  186. X
  187. X#ifndef YY_BUF_SIZE
  188. X#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */
  189. X#endif
  190. X
  191. Xtypedef struct yy_buffer_state *YY_BUFFER_STATE;
  192. X
  193. X%% section 1 definitions go here
  194. X
  195. X/* done after the current pattern has been matched and before the
  196. X * corresponding action - sets up yytext
  197. X */
  198. X#define YY_DO_BEFORE_ACTION \
  199. X    yytext = yy_bp; \
  200. X%% code to fiddle yytext and yyleng for yymore() goes here
  201. X    yy_hold_char = *yy_cp; \
  202. X    *yy_cp = '\0'; \
  203. X    yy_c_buf_p = yy_cp;
  204. X
  205. X#define EOB_ACT_CONTINUE_SCAN 0
  206. X#define EOB_ACT_END_OF_FILE 1
  207. X#define EOB_ACT_LAST_MATCH 2
  208. X
  209. X/* return all but the first 'n' matched characters back to the input stream */
  210. X#define yyless(n) \
  211. X    do \
  212. X        { \
  213. X        /* undo effects of setting up yytext */ \
  214. X        *yy_cp = yy_hold_char; \
  215. X        yy_c_buf_p = yy_cp = yy_bp + n; \
  216. X        YY_DO_BEFORE_ACTION; /* set up yytext again */ \
  217. X        } \
  218. X    while ( 0 )
  219. X
  220. X#define unput(c) yyunput( c, yytext )
  221. X
  222. X
  223. Xstruct yy_buffer_state
  224. X    {
  225. X    FILE *yy_input_file;
  226. X
  227. X    YY_CHAR *yy_ch_buf;        /* input buffer */
  228. X    YY_CHAR *yy_buf_pos;    /* current position in input buffer */
  229. X
  230. X    /* size of input buffer in bytes, not including room for EOB characters*/
  231. X    int yy_buf_size;    
  232. X
  233. X    /* number of characters read into yy_ch_buf, not including EOB characters */
  234. X    int yy_n_chars;
  235. X
  236. X    int yy_eof_status;        /* whether we've seen an EOF on this buffer */
  237. X#define EOF_NOT_SEEN 0
  238. X    /* "pending" happens when the EOF has been seen but there's still
  239. X     * some text process
  240. X     */
  241. X#define EOF_PENDING 1
  242. X#define EOF_DONE 2
  243. X    };
  244. X
  245. Xstatic YY_BUFFER_STATE yy_current_buffer;
  246. X
  247. X/* we provide macros for accessing buffer states in case in the
  248. X * future we want to put the buffer states in a more general
  249. X * "scanner state"
  250. X */
  251. X#define YY_CURRENT_BUFFER yy_current_buffer
  252. X
  253. X
  254. X/* yy_hold_char holds the character lost when yytext is formed */
  255. Xstatic YY_CHAR yy_hold_char;
  256. X
  257. Xstatic int yy_n_chars;        /* number of characters read into yy_ch_buf */
  258. X
  259. X
  260. X
  261. X#ifndef YY_USER_ACTION
  262. X#define YY_USER_ACTION
  263. X#endif
  264. X
  265. X#ifndef YY_USER_INIT
  266. X#define YY_USER_INIT
  267. X#endif
  268. X
  269. Xextern YY_CHAR *yytext;
  270. Xextern int yyleng;
  271. Xextern FILE *yyin, *yyout;
  272. X
  273. XYY_CHAR *yytext;
  274. Xint yyleng;
  275. X
  276. XFILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
  277. X
  278. X%% data tables for the DFA go here
  279. X
  280. X/* these variables are all declared out here so that section 3 code can
  281. X * manipulate them
  282. X */
  283. X/* points to current character in buffer */
  284. Xstatic YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0;
  285. Xstatic int yy_init = 1;        /* whether we need to initialize */
  286. Xstatic int yy_start = 0;    /* start state number */
  287. X
  288. X/* flag which is used to allow yywrap()'s to do buffer switches
  289. X * instead of setting up a fresh yyin.  A bit of a hack ...
  290. X */
  291. Xstatic int yy_did_buffer_switch_on_eof;
  292. X
  293. Xstatic yy_state_type yy_get_previous_state YY_PROTO(( void ));
  294. Xstatic yy_state_type yy_try_NUL_trans YY_PROTO(( register yy_state_type current_state ));
  295. Xstatic int yy_get_next_buffer YY_PROTO(( void ));
  296. Xstatic void yyunput YY_PROTO(( YY_CHAR c, register YY_CHAR *buf_ptr ));
  297. Xvoid yyrestart YY_PROTO(( FILE *input_file ));
  298. Xvoid yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
  299. Xvoid yy_load_buffer_state YY_PROTO(( void ));
  300. XYY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
  301. Xvoid yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
  302. Xvoid yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
  303. X
  304. X#define yy_new_buffer yy_create_buffer
  305. X
  306. X#ifdef __cplusplus
  307. Xstatic int yyinput YY_PROTO(( void ));
  308. X#else
  309. Xstatic int input YY_PROTO(( void ));
  310. X#endif
  311. X
  312. XYY_DECL
  313. X    {
  314. X    register yy_state_type yy_current_state;
  315. X    register YY_CHAR *yy_cp, *yy_bp;
  316. X    register int yy_act;
  317. X
  318. X%% user's declarations go here
  319. X
  320. X    if ( yy_init )
  321. X    {
  322. X    YY_USER_INIT;
  323. X
  324. X    if ( ! yy_start )
  325. X        yy_start = 1;    /* first start state */
  326. X
  327. X    if ( ! yyin )
  328. X        yyin = stdin;
  329. X
  330. X    if ( ! yyout )
  331. X        yyout = stdout;
  332. X
  333. X    if ( yy_current_buffer )
  334. X        yy_init_buffer( yy_current_buffer, yyin );
  335. X    else
  336. X        yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
  337. X
  338. X    yy_load_buffer_state();
  339. X
  340. X    yy_init = 0;
  341. X    }
  342. X
  343. X    while ( 1 )        /* loops until end-of-file is reached */
  344. X    {
  345. X%% yymore()-related code goes here
  346. X    yy_cp = yy_c_buf_p;
  347. X
  348. X    /* support of yytext */
  349. X    *yy_cp = yy_hold_char;
  350. X
  351. X    /* yy_bp points to the position in yy_ch_buf of the start of the
  352. X     * current run.
  353. X     */
  354. X    yy_bp = yy_cp;
  355. X
  356. X%% code to set up and find next match goes here
  357. X
  358. Xyy_find_action:
  359. X%% code to find the action number goes here
  360. X
  361. X    YY_DO_BEFORE_ACTION;
  362. X    YY_USER_ACTION;
  363. X
  364. Xdo_action:    /* this label is used only to access EOF actions */
  365. X
  366. X%% debug code goes here
  367. X
  368. X    switch ( yy_act )
  369. X        {
  370. X%% actions go here
  371. X
  372. X        case YY_END_OF_BUFFER:
  373. X        {
  374. X        /* amount of text matched not including the EOB char */
  375. X        int yy_amount_of_matched_text = yy_cp - yytext - 1;
  376. X
  377. X        /* undo the effects of YY_DO_BEFORE_ACTION */
  378. X        *yy_cp = yy_hold_char;
  379. X
  380. X        /* note that here we test for yy_c_buf_p "<=" to the position
  381. X         * of the first EOB in the buffer, since yy_c_buf_p will
  382. X         * already have been incremented past the NUL character
  383. X         * (since all states make transitions on EOB to the end-
  384. X         * of-buffer state).  Contrast this with the test in yyinput().
  385. X         */
  386. X        if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  387. X            /* this was really a NUL */
  388. X            {
  389. X            yy_state_type yy_next_state;
  390. X
  391. X            yy_c_buf_p = yytext + yy_amount_of_matched_text;
  392. X
  393. X            yy_current_state = yy_get_previous_state();
  394. X
  395. X            /* okay, we're now positioned to make the
  396. X             * NUL transition.  We couldn't have
  397. X             * yy_get_previous_state() go ahead and do it
  398. X             * for us because it doesn't know how to deal
  399. X             * with the possibility of jamming (and we
  400. X             * don't want to build jamming into it because
  401. X             * then it will run more slowly)
  402. X             */
  403. X
  404. X            yy_next_state = yy_try_NUL_trans( yy_current_state );
  405. X
  406. X            yy_bp = yytext + YY_MORE_ADJ;
  407. X
  408. X            if ( yy_next_state )
  409. X            {
  410. X            /* consume the NUL */
  411. X            yy_cp = ++yy_c_buf_p;
  412. X            yy_current_state = yy_next_state;
  413. X            goto yy_match;
  414. X            }
  415. X
  416. X            else
  417. X            {
  418. X%% code to do backtracking for compressed tables and set up yy_cp goes here
  419. X            goto yy_find_action;
  420. X            }
  421. X            }
  422. X
  423. X        else switch ( yy_get_next_buffer() )
  424. X            {
  425. X            case EOB_ACT_END_OF_FILE:
  426. X            {
  427. X            yy_did_buffer_switch_on_eof = 0;
  428. X
  429. X            if ( yywrap() )
  430. X                {
  431. X                /* note: because we've taken care in
  432. X                 * yy_get_next_buffer() to have set up yytext,
  433. X                 * we can now set up yy_c_buf_p so that if some
  434. X                 * total hoser (like flex itself) wants
  435. X                 * to call the scanner after we return the
  436. X                 * YY_NULL, it'll still work - another YY_NULL
  437. X                 * will get returned.
  438. X                 */
  439. X                yy_c_buf_p = yytext + YY_MORE_ADJ;
  440. X
  441. X                yy_act = YY_STATE_EOF((yy_start - 1) / 2);
  442. X                goto do_action;
  443. X                }
  444. X
  445. X            else
  446. X                {
  447. X                if ( ! yy_did_buffer_switch_on_eof )
  448. X                YY_NEW_FILE;
  449. X                }
  450. X            }
  451. X            break;
  452. X
  453. X            case EOB_ACT_CONTINUE_SCAN:
  454. X            yy_c_buf_p = yytext + yy_amount_of_matched_text;
  455. X
  456. X            yy_current_state = yy_get_previous_state();
  457. X
  458. X            yy_cp = yy_c_buf_p;
  459. X            yy_bp = yytext + YY_MORE_ADJ;
  460. X            goto yy_match;
  461. X
  462. X            case EOB_ACT_LAST_MATCH:
  463. X            yy_c_buf_p =
  464. X                &yy_current_buffer->yy_ch_buf[yy_n_chars];
  465. X
  466. X            yy_current_state = yy_get_previous_state();
  467. X
  468. X            yy_cp = yy_c_buf_p;
  469. X            yy_bp = yytext + YY_MORE_ADJ;
  470. X            goto yy_find_action;
  471. X            }
  472. X        break;
  473. X        }
  474. X
  475. X        default:
  476. X#ifdef FLEX_DEBUG
  477. X        printf( "action # %d\n", yy_act );
  478. X#endif
  479. X        YY_FATAL_ERROR(
  480. X            "fatal flex scanner internal error--no action found" );
  481. X        }
  482. X    }
  483. X    }
  484. X
  485. X
  486. X/* yy_get_next_buffer - try to read in a new buffer
  487. X *
  488. X * synopsis
  489. X *     int yy_get_next_buffer();
  490. X *     
  491. X * returns a code representing an action
  492. X *     EOB_ACT_LAST_MATCH - 
  493. X *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  494. X *     EOB_ACT_END_OF_FILE - end of file
  495. X */
  496. X
  497. Xstatic int yy_get_next_buffer()
  498. X
  499. X    {
  500. X    register YY_CHAR *dest = yy_current_buffer->yy_ch_buf;
  501. X    register YY_CHAR *source = yytext - 1; /* copy prev. char, too */
  502. X    register int number_to_move, i;
  503. X    int ret_val;
  504. X
  505. X    if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
  506. X    YY_FATAL_ERROR(
  507. X        "fatal flex scanner internal error--end of buffer missed" );
  508. X
  509. X    /* try to read more data */
  510. X
  511. X    /* first move last chars to start of buffer */
  512. X    number_to_move = yy_c_buf_p - yytext;
  513. X
  514. X    for ( i = 0; i < number_to_move; ++i )
  515. X    *(dest++) = *(source++);
  516. X
  517. X    if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN )
  518. X    /* don't do the read, it's not guaranteed to return an EOF,
  519. X     * just force an EOF
  520. X     */
  521. X    yy_n_chars = 0;
  522. X
  523. X    else
  524. X    {
  525. X    int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1;
  526. X
  527. X    if ( num_to_read > YY_READ_BUF_SIZE )
  528. X        num_to_read = YY_READ_BUF_SIZE;
  529. X
  530. X    else if ( num_to_read <= 0 )
  531. X        YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" );
  532. X
  533. X    /* read in more data */
  534. X    YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
  535. X          yy_n_chars, num_to_read );
  536. X    }
  537. X
  538. X    if ( yy_n_chars == 0 )
  539. X    {
  540. X    if ( number_to_move == 1 )
  541. X        {
  542. X        ret_val = EOB_ACT_END_OF_FILE;
  543. X        yy_current_buffer->yy_eof_status = EOF_DONE;
  544. X        }
  545. X
  546. X    else
  547. X        {
  548. X        ret_val = EOB_ACT_LAST_MATCH;
  549. X        yy_current_buffer->yy_eof_status = EOF_PENDING;
  550. X        }
  551. X    }
  552. X
  553. X    else
  554. X    ret_val = EOB_ACT_CONTINUE_SCAN;
  555. X
  556. X    yy_n_chars += number_to_move;
  557. X    yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
  558. X    yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
  559. X
  560. X    /* yytext begins at the second character in yy_ch_buf; the first
  561. X     * character is the one which preceded it before reading in the latest
  562. X     * buffer; it needs to be kept around in case it's a newline, so
  563. X     * yy_get_previous_state() will have with '^' rules active
  564. X     */
  565. X
  566. X    yytext = &yy_current_buffer->yy_ch_buf[1];
  567. X
  568. X    return ( ret_val );
  569. X    }
  570. X
  571. X
  572. X/* yy_get_previous_state - get the state just before the EOB char was reached
  573. X *
  574. X * synopsis
  575. X *     yy_state_type yy_get_previous_state();
  576. X */
  577. X
  578. Xstatic yy_state_type yy_get_previous_state()
  579. X
  580. X    {
  581. X    register yy_state_type yy_current_state;
  582. X    register YY_CHAR *yy_cp;
  583. X
  584. X%% code to get the start state into yy_current_state goes here
  585. X
  586. X    for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
  587. X    {
  588. X%% code to find the next state goes here
  589. X    }
  590. X
  591. X    return ( yy_current_state );
  592. X    }
  593. X
  594. X
  595. X/* yy_try_NUL_trans - try to make a transition on the NUL character
  596. X *
  597. X * synopsis
  598. X *     next_state = yy_try_NUL_trans( current_state );
  599. X */
  600. X
  601. X#ifdef YY_USE_PROTOS
  602. Xstatic yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state )
  603. X#else
  604. Xstatic yy_state_type yy_try_NUL_trans( yy_current_state )
  605. Xregister yy_state_type yy_current_state;
  606. X#endif
  607. X
  608. X    {
  609. X    register int yy_is_jam;
  610. X%% code to find the next state, and perhaps do backtracking, goes here
  611. X
  612. X    return ( yy_is_jam ? 0 : yy_current_state );
  613. X    }
  614. X
  615. X
  616. X#ifdef YY_USE_PROTOS
  617. Xstatic void yyunput( YY_CHAR c, register YY_CHAR *yy_bp )
  618. X#else
  619. Xstatic void yyunput( c, yy_bp )
  620. XYY_CHAR c;
  621. Xregister YY_CHAR *yy_bp;
  622. X#endif
  623. X
  624. X    {
  625. X    register YY_CHAR *yy_cp = yy_c_buf_p;
  626. X
  627. X    /* undo effects of setting up yytext */
  628. X    *yy_cp = yy_hold_char;
  629. X
  630. X    if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  631. X    { /* need to shift things up to make room */
  632. X    register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
  633. X    register YY_CHAR *dest =
  634. X        &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2];
  635. X    register YY_CHAR *source =
  636. X        &yy_current_buffer->yy_ch_buf[number_to_move];
  637. X
  638. X    while ( source > yy_current_buffer->yy_ch_buf )
  639. X        *--dest = *--source;
  640. X
  641. X    yy_cp += dest - source;
  642. X    yy_bp += dest - source;
  643. X    yy_n_chars = yy_current_buffer->yy_buf_size;
  644. X
  645. X    if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  646. X        YY_FATAL_ERROR( "flex scanner push-back overflow" );
  647. X    }
  648. X
  649. X    if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
  650. X    yy_cp[-2] = '\n';
  651. X
  652. X    *--yy_cp = c;
  653. X
  654. X    /* note: the formal parameter *must* be called "yy_bp" for this
  655. X     *       macro to now work correctly
  656. X     */
  657. X    YY_DO_BEFORE_ACTION; /* set up yytext again */
  658. X    }
  659. X
  660. X
  661. X#ifdef __cplusplus
  662. Xstatic int yyinput()
  663. X#else
  664. Xstatic int input()
  665. X#endif
  666. X
  667. X    {
  668. X    int c;
  669. X    YY_CHAR *yy_cp = yy_c_buf_p;
  670. X
  671. X    *yy_cp = yy_hold_char;
  672. X
  673. X    if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
  674. X    {
  675. X    /* yy_c_buf_p now points to the character we want to return.
  676. X     * If this occurs *before* the EOB characters, then it's a
  677. X     * valid NUL; if not, then we've hit the end of the buffer.
  678. X     */
  679. X    if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  680. X        /* this was really a NUL */
  681. X        *yy_c_buf_p = '\0';
  682. X
  683. X    else
  684. X        { /* need more input */
  685. X        yytext = yy_c_buf_p;
  686. X        ++yy_c_buf_p;
  687. X
  688. X        switch ( yy_get_next_buffer() )
  689. X        {
  690. X        case EOB_ACT_END_OF_FILE:
  691. X            {
  692. X            if ( yywrap() )
  693. X            {
  694. X            yy_c_buf_p = yytext + YY_MORE_ADJ;
  695. X            return ( EOF );
  696. X            }
  697. X
  698. X            YY_NEW_FILE;
  699. X
  700. X#ifdef __cplusplus
  701. X            return ( yyinput() );
  702. X#else
  703. X            return ( input() );
  704. X#endif
  705. X            }
  706. X            break;
  707. X
  708. X        case EOB_ACT_CONTINUE_SCAN:
  709. X            yy_c_buf_p = yytext + YY_MORE_ADJ;
  710. X            break;
  711. X
  712. X        case EOB_ACT_LAST_MATCH:
  713. X#ifdef __cplusplus
  714. X            YY_FATAL_ERROR( "unexpected last match in yyinput()" );
  715. X#else
  716. X            YY_FATAL_ERROR( "unexpected last match in input()" );
  717. X#endif
  718. X        }
  719. X        }
  720. X    }
  721. X
  722. X    c = *yy_c_buf_p;
  723. X    yy_hold_char = *++yy_c_buf_p;
  724. X
  725. X    return ( c );
  726. X    }
  727. X
  728. X
  729. X#ifdef YY_USE_PROTOS
  730. Xvoid yyrestart( FILE *input_file )
  731. X#else
  732. Xvoid yyrestart( input_file )
  733. XFILE *input_file;
  734. X#endif
  735. X
  736. X    {
  737. X    yy_init_buffer( yy_current_buffer, input_file );
  738. X    yy_load_buffer_state();
  739. X    }
  740. X
  741. X
  742. X#ifdef YY_USE_PROTOS
  743. Xvoid yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
  744. X#else
  745. Xvoid yy_switch_to_buffer( new_buffer )
  746. XYY_BUFFER_STATE new_buffer;
  747. X#endif
  748. X
  749. X    {
  750. X    if ( yy_current_buffer == new_buffer )
  751. X    return;
  752. X
  753. X    if ( yy_current_buffer )
  754. X    {
  755. X    /* flush out information for old buffer */
  756. X    *yy_c_buf_p = yy_hold_char;
  757. X    yy_current_buffer->yy_buf_pos = yy_c_buf_p;
  758. X    yy_current_buffer->yy_n_chars = yy_n_chars;
  759. X    }
  760. X
  761. X    yy_current_buffer = new_buffer;
  762. X    yy_load_buffer_state();
  763. X
  764. X    /* we don't actually know whether we did this switch during
  765. X     * EOF (yywrap()) processing, but the only time this flag
  766. X     * is looked at is after yywrap() is called, so it's safe
  767. X     * to go ahead and always set it.
  768. X     */
  769. X    yy_did_buffer_switch_on_eof = 1;
  770. X    }
  771. X
  772. X
  773. X#ifdef YY_USE_PROTOS
  774. Xvoid yy_load_buffer_state( void )
  775. X#else
  776. Xvoid yy_load_buffer_state()
  777. X#endif
  778. X
  779. X    {
  780. X    yy_n_chars = yy_current_buffer->yy_n_chars;
  781. X    yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
  782. X    yyin = yy_current_buffer->yy_input_file;
  783. X    yy_hold_char = *yy_c_buf_p;
  784. X    }
  785. X
  786. X
  787. X#ifdef YY_USE_PROTOS
  788. XYY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
  789. X#else
  790. XYY_BUFFER_STATE yy_create_buffer( file, size )
  791. XFILE *file;
  792. Xint size;
  793. X#endif
  794. X
  795. X    {
  796. X    YY_BUFFER_STATE b;
  797. X
  798. X    b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) );
  799. X
  800. X    if ( ! b )
  801. X    YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  802. X
  803. X    b->yy_buf_size = size;
  804. X
  805. X    /* yy_ch_buf has to be 2 characters longer than the size given because
  806. X     * we need to put in 2 end-of-buffer characters.
  807. X     */
  808. X    b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) );
  809. X
  810. X    if ( ! b->yy_ch_buf )
  811. X    YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  812. X
  813. X    yy_init_buffer( b, file );
  814. X
  815. X    return ( b );
  816. X    }
  817. X
  818. X
  819. X#ifdef YY_USE_PROTOS
  820. Xvoid yy_delete_buffer( YY_BUFFER_STATE b )
  821. X#else
  822. Xvoid yy_delete_buffer( b )
  823. XYY_BUFFER_STATE b;
  824. X#endif
  825. X
  826. X    {
  827. X    if ( b == yy_current_buffer )
  828. X    yy_current_buffer = (YY_BUFFER_STATE) 0;
  829. X
  830. X    free( (char *) b->yy_ch_buf );
  831. X    free( (char *) b );
  832. X    }
  833. X
  834. X
  835. X#ifdef YY_USE_PROTOS
  836. Xvoid yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
  837. X#else
  838. Xvoid yy_init_buffer( b, file )
  839. XYY_BUFFER_STATE b;
  840. XFILE *file;
  841. X#endif
  842. X
  843. X    {
  844. X    b->yy_input_file = file;
  845. X
  846. X    /* we put in the '\n' and start reading from [1] so that an
  847. X     * initial match-at-newline will be true.
  848. X     */
  849. X
  850. X    b->yy_ch_buf[0] = '\n';
  851. X    b->yy_n_chars = 1;
  852. X
  853. X    /* we always need two end-of-buffer characters.  The first causes
  854. X     * a transition to the end-of-buffer state.  The second causes
  855. X     * a jam in that state.
  856. X     */
  857. X    b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
  858. X    b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR;
  859. X
  860. X    b->yy_buf_pos = &b->yy_ch_buf[1];
  861. X
  862. X    b->yy_eof_status = EOF_NOT_SEEN;
  863. X    }
  864. END_OF_FILE
  865. if test 19618 -ne `wc -c <'flex.skel'`; then
  866.     echo shar: \"'flex.skel'\" unpacked with wrong size!
  867. fi
  868. # end of 'flex.skel'
  869. fi
  870. if test -f 'main.c' -a "${1}" != "-c" ; then 
  871.   echo shar: Will not clobber existing file \"'main.c'\"
  872. else
  873. echo shar: Extracting \"'main.c'\" \(20291 characters\)
  874. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  875. X/* flex - tool to generate fast lexical analyzers */
  876. X
  877. X/*-
  878. X * Copyright (c) 1990 The Regents of the University of California.
  879. X * All rights reserved.
  880. X *
  881. X * This code is derived from software contributed to Berkeley by
  882. X * Vern Paxson.
  883. X * 
  884. X * The United States Government has rights in this work pursuant
  885. X * to contract no. DE-AC03-76SF00098 between the United States
  886. X * Department of Energy and the University of California.
  887. X *
  888. X * Redistribution and use in source and binary forms are permitted provided
  889. X * that: (1) source distributions retain this entire copyright notice and
  890. X * comment, and (2) distributions including binaries display the following
  891. X * acknowledgement:  ``This product includes software developed by the
  892. X * University of California, Berkeley and its contributors'' in the
  893. X * documentation or other materials provided with the distribution and in
  894. X * all advertising materials mentioning features or use of this software.
  895. X * Neither the name of the University nor the names of its contributors may
  896. X * be used to endorse or promote products derived from this software without
  897. X * specific prior written permission.
  898. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  899. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  900. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  901. X */
  902. X
  903. X#ifndef lint
  904. Xchar copyright[] =
  905. X"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
  906. X All rights reserved.\n";
  907. X#endif /* not lint */
  908. X
  909. X#ifndef lint
  910. Xstatic char rcsid[] =
  911. X    "@(#) $Header: WPL:Generators/flex-2.3/RCS/main.c,v 1.2 90/07/15 01:17:37 loftus Exp $ (LBL)";
  912. X#endif
  913. X
  914. X
  915. X#include "flexdef.h"
  916. X
  917. Xstatic char flex_version[] = "2.3";
  918. X
  919. X
  920. X/* declare functions that have forward references */
  921. X
  922. Xvoid flexinit PROTO((int, char**));
  923. Xvoid readin PROTO(());
  924. Xvoid set_up_initial_allocations PROTO(());
  925. X
  926. X
  927. X/* these globals are all defined and commented in flexdef.h */
  928. Xint printstats, syntaxerror, eofseen, ddebug, trace, spprdflt;
  929. Xint interactive, caseins, useecs, fulltbl, usemecs;
  930. Xint fullspd, gen_line_dirs, performance_report, backtrack_report, csize;
  931. Xint yymore_used, reject, real_reject, continued_action;
  932. Xint yymore_really_used, reject_really_used;
  933. Xint datapos, dataline, linenum;
  934. XFILE *skelfile = NULL;
  935. Xchar *infilename = NULL;
  936. Xint onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
  937. Xint onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
  938. Xint current_mns, num_rules, current_max_rules, lastnfa;
  939. Xint *firstst, *lastst, *finalst, *transchar, *trans1, *trans2;
  940. Xint *accptnum, *assoc_rule, *state_type, *rule_type, *rule_linenum;
  941. Xint current_state_type;
  942. Xint variable_trailing_context_rules;
  943. Xint numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
  944. Xint protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE];
  945. Xint numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1];
  946. Xint tecbck[CSIZE + 1];
  947. Xint *xlation = (int *) 0;
  948. Xint num_xlations;
  949. Xint lastsc, current_max_scs, *scset, *scbol, *scxclu, *sceof, *actvsc;
  950. Xchar **scname;
  951. Xint current_max_dfa_size, current_max_xpairs;
  952. Xint current_max_template_xpairs, current_max_dfas;
  953. Xint lastdfa, *nxt, *chk, *tnxt;
  954. Xint *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz;
  955. Xunion dfaacc_union *dfaacc;
  956. Xint *accsiz, *dhash, numas;
  957. Xint numsnpairs, jambase, jamstate;
  958. Xint lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse;
  959. Xint current_max_ccl_tbl_size;
  960. XChar *ccltbl;
  961. Xchar *starttime, *endtime, nmstr[MAXLINE];
  962. Xint sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
  963. Xint tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
  964. Xint num_backtracking, bol_needed;
  965. XFILE *temp_action_file;
  966. XFILE *backtrack_file;
  967. Xint end_of_buffer_state;
  968. Xchar *action_file_name = NULL;
  969. Xchar **input_files;
  970. Xint num_input_files;
  971. Xchar *program_name;
  972. X
  973. X#ifndef SHORT_FILE_NAMES
  974. Xstatic char *outfile = "lex.yy.c";
  975. X#else
  976. Xstatic char *outfile = "lexyy.c";
  977. X#endif
  978. Xstatic int outfile_created = 0;
  979. Xstatic int use_stdout;
  980. Xstatic char *skelname = NULL;
  981. X
  982. X#ifdef AMIGA
  983. Xchar *                                                                         
  984. XTmpFileName(template)                                                          
  985. Xchar *template;                                                                
  986. X{                                                                              
  987. X    static char Template[256];                                                 
  988. X    static unsigned short Idx;                                                 
  989. X                                                                               
  990. X    sprintf(Template, "%s-%08lx.TMP", template, (long)FindTask(NULL) + Idx++); 
  991. X    return(Template);                                                          
  992. X}
  993. X#endif
  994. X
  995. X
  996. Xint main( argc, argv )
  997. Xint argc;
  998. Xchar **argv;
  999. X
  1000. X    {
  1001. X    flexinit( argc, argv );
  1002. X
  1003. X    readin();
  1004. X
  1005. X    if ( syntaxerror )
  1006. X    flexend( 1 );
  1007. X
  1008. X    if ( yymore_really_used == REALLY_USED )
  1009. X    yymore_used = true;
  1010. X    else if ( yymore_really_used == REALLY_NOT_USED )
  1011. X    yymore_used = false;
  1012. X
  1013. X    if ( reject_really_used == REALLY_USED )
  1014. X    reject = true;
  1015. X    else if ( reject_really_used == REALLY_NOT_USED )
  1016. X    reject = false;
  1017. X
  1018. X    if ( performance_report )
  1019. X    {
  1020. X    if ( interactive )
  1021. X        fprintf( stderr,
  1022. X             "-I (interactive) entails a minor performance penalty\n" );
  1023. X
  1024. X    if ( yymore_used )
  1025. X        fprintf( stderr, "yymore() entails a minor performance penalty\n" );
  1026. X
  1027. X    if ( reject )
  1028. X        fprintf( stderr, "REJECT entails a large performance penalty\n" );
  1029. X
  1030. X    if ( variable_trailing_context_rules )
  1031. X        fprintf( stderr,
  1032. X"Variable trailing context rules entail a large performance penalty\n" );
  1033. X    }
  1034. X
  1035. X    if ( reject )
  1036. X    real_reject = true;
  1037. X
  1038. X    if ( variable_trailing_context_rules )
  1039. X    reject = true;
  1040. X
  1041. X    if ( (fulltbl || fullspd) && reject )
  1042. X    {
  1043. X    if ( real_reject )
  1044. X        flexerror( "REJECT cannot be used with -f or -F" );
  1045. X    else
  1046. X        flexerror(
  1047. X    "variable trailing context rules cannot be used with -f or -F" );
  1048. X    }
  1049. X
  1050. X    ntod();
  1051. X
  1052. X    /* generate the C state transition tables from the DFA */
  1053. X    make_tables();
  1054. X
  1055. X    /* note, flexend does not return.  It exits with its argument as status. */
  1056. X
  1057. X    flexend( 0 );
  1058. X
  1059. X    /*NOTREACHED*/
  1060. X    }
  1061. X
  1062. X
  1063. X/* flexend - terminate flex
  1064. X *
  1065. X * synopsis
  1066. X *    int status;
  1067. X *    flexend( status );
  1068. X *
  1069. X *    status is exit status.
  1070. X *
  1071. X * note
  1072. X *    This routine does not return.
  1073. X */
  1074. X
  1075. Xvoid flexend( status )
  1076. Xint status;
  1077. X
  1078. X    {
  1079. X    int tblsiz;
  1080. X    char *flex_gettime();
  1081. X
  1082. X    if ( skelfile != NULL )
  1083. X    {
  1084. X    if ( ferror( skelfile ) )
  1085. X        flexfatal( "error occurred when writing skeleton file" );
  1086. X
  1087. X    else if ( fclose( skelfile ) )
  1088. X        flexfatal( "error occurred when closing skeleton file" );
  1089. X    }
  1090. X
  1091. X    if ( temp_action_file )
  1092. X    {
  1093. X    if ( ferror( temp_action_file ) )
  1094. X        flexfatal( "error occurred when writing temporary action file" );
  1095. X
  1096. X    else if ( fclose( temp_action_file ) )
  1097. X        flexfatal( "error occurred when closing temporary action file" );
  1098. X
  1099. X    else if ( unlink( action_file_name ) )
  1100. X        flexfatal( "error occurred when deleting temporary action file" );
  1101. X    }
  1102. X
  1103. X    if ( status != 0 && outfile_created )
  1104. X    {
  1105. X    if ( ferror( stdout ) )
  1106. X        flexfatal( "error occurred when writing output file" );
  1107. X
  1108. X    else if ( fclose( stdout ) )
  1109. X        flexfatal( "error occurred when closing output file" );
  1110. X
  1111. X    else if ( unlink( outfile ) )
  1112. X        flexfatal( "error occurred when deleting output file" );
  1113. X    }
  1114. X
  1115. X    if ( backtrack_report && backtrack_file )
  1116. X    {
  1117. X    if ( num_backtracking == 0 )
  1118. X        fprintf( backtrack_file, "No backtracking.\n" );
  1119. X    else if ( fullspd || fulltbl )
  1120. X        fprintf( backtrack_file,
  1121. X             "%d backtracking (non-accepting) states.\n",
  1122. X             num_backtracking );
  1123. X    else
  1124. X        fprintf( backtrack_file, "Compressed tables always backtrack.\n" );
  1125. X
  1126. X    if ( ferror( backtrack_file ) )
  1127. X        flexfatal( "error occurred when writing backtracking file" );
  1128. X
  1129. X    else if ( fclose( backtrack_file ) )
  1130. X        flexfatal( "error occurred when closing backtracking file" );
  1131. X    }
  1132. X
  1133. X    if ( printstats )
  1134. X    {
  1135. X    endtime = flex_gettime();
  1136. X
  1137. X    fprintf( stderr, "%s version %s usage statistics:\n", program_name,
  1138. X         flex_version );
  1139. X    fprintf( stderr, "  started at %s, finished at %s\n",
  1140. X         starttime, endtime );
  1141. X
  1142. X    fprintf( stderr, "  scanner options: -" );
  1143. X
  1144. X    if ( backtrack_report )
  1145. X        putc( 'b', stderr );
  1146. X    if ( ddebug )
  1147. X        putc( 'd', stderr );
  1148. X    if ( interactive )
  1149. X        putc( 'I', stderr );
  1150. X    if ( caseins )
  1151. X        putc( 'i', stderr );
  1152. X    if ( ! gen_line_dirs )
  1153. X        putc( 'L', stderr );
  1154. X    if ( performance_report )
  1155. X        putc( 'p', stderr );
  1156. X    if ( spprdflt )
  1157. X        putc( 's', stderr );
  1158. X    if ( use_stdout )
  1159. X        putc( 't', stderr );
  1160. X    if ( trace )
  1161. X        putc( 'T', stderr );
  1162. X    if ( printstats )
  1163. X        putc( 'v', stderr );    /* always true! */
  1164. X    if ( csize == 256 )
  1165. X        putc( '8', stderr );
  1166. X
  1167. X    fprintf( stderr, " -C" );
  1168. X
  1169. X    if ( fulltbl )
  1170. X        putc( 'f', stderr );
  1171. X    if ( fullspd )
  1172. X        putc( 'F', stderr );
  1173. X    if ( useecs )
  1174. X        putc( 'e', stderr );
  1175. X    if ( usemecs )
  1176. X        putc( 'm', stderr );
  1177. X
  1178. X    if ( strcmp( skelname, DEFAULT_SKELETON_FILE ) )
  1179. X        fprintf( stderr, " -S%s", skelname );
  1180. X
  1181. X    putc( '\n', stderr );
  1182. X
  1183. X    fprintf( stderr, "  %d/%d NFA states\n", lastnfa, current_mns );
  1184. X    fprintf( stderr, "  %d/%d DFA states (%d words)\n", lastdfa,
  1185. X         current_max_dfas, totnst );
  1186. X    fprintf( stderr,
  1187. X         "  %d rules\n", num_rules - 1 /* - 1 for def. rule */ );
  1188. X
  1189. X    if ( num_backtracking == 0 )
  1190. X        fprintf( stderr, "  No backtracking\n" );
  1191. X    else if ( fullspd || fulltbl )
  1192. X        fprintf( stderr, "  %d backtracking (non-accepting) states\n",
  1193. X             num_backtracking );
  1194. X    else
  1195. X        fprintf( stderr, "  compressed tables always backtrack\n" );
  1196. X
  1197. X    if ( bol_needed )
  1198. X        fprintf( stderr, "  Beginning-of-line patterns used\n" );
  1199. X
  1200. X    fprintf( stderr, "  %d/%d start conditions\n", lastsc,
  1201. X         current_max_scs );
  1202. X    fprintf( stderr, "  %d epsilon states, %d double epsilon states\n",
  1203. X         numeps, eps2 );
  1204. X
  1205. X    if ( lastccl == 0 )
  1206. X        fprintf( stderr, "  no character classes\n" );
  1207. X    else
  1208. X        fprintf( stderr,
  1209. X    "  %d/%d character classes needed %d/%d words of storage, %d reused\n",
  1210. X             lastccl, current_maxccls,
  1211. X             cclmap[lastccl] + ccllen[lastccl],
  1212. X             current_max_ccl_tbl_size, cclreuse );
  1213. X
  1214. X    fprintf( stderr, "  %d state/nextstate pairs created\n", numsnpairs );
  1215. X    fprintf( stderr, "  %d/%d unique/duplicate transitions\n",
  1216. X         numuniq, numdup );
  1217. X
  1218. X    if ( fulltbl )
  1219. X        {
  1220. X        tblsiz = lastdfa * numecs;
  1221. X        fprintf( stderr, "  %d table entries\n", tblsiz );
  1222. X        }
  1223. X
  1224. X    else
  1225. X        {
  1226. X        tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend;
  1227. X
  1228. X        fprintf( stderr, "  %d/%d base-def entries created\n",
  1229. X             lastdfa + numtemps, current_max_dfas );
  1230. X        fprintf( stderr, "  %d/%d (peak %d) nxt-chk entries created\n",
  1231. X             tblend, current_max_xpairs, peakpairs );
  1232. X        fprintf( stderr,
  1233. X             "  %d/%d (peak %d) template nxt-chk entries created\n",
  1234. X             numtemps * nummecs, current_max_template_xpairs,
  1235. X             numtemps * numecs );
  1236. X        fprintf( stderr, "  %d empty table entries\n", nummt );
  1237. X        fprintf( stderr, "  %d protos created\n", numprots );
  1238. X        fprintf( stderr, "  %d templates created, %d uses\n",
  1239. X             numtemps, tmpuses );
  1240. X        }
  1241. X
  1242. X    if ( useecs )
  1243. X        {
  1244. X        tblsiz = tblsiz + csize;
  1245. X        fprintf( stderr, "  %d/%d equivalence classes created\n",
  1246. X             numecs, csize );
  1247. X        }
  1248. X
  1249. X    if ( usemecs )
  1250. X        {
  1251. X        tblsiz = tblsiz + numecs;
  1252. X        fprintf( stderr, "  %d/%d meta-equivalence classes created\n",
  1253. X             nummecs, csize );
  1254. X        }
  1255. X
  1256. X    fprintf( stderr, "  %d (%d saved) hash collisions, %d DFAs equal\n",
  1257. X         hshcol, hshsave, dfaeql );
  1258. X    fprintf( stderr, "  %d sets of reallocations needed\n", num_reallocs );
  1259. X    fprintf( stderr, "  %d total table entries needed\n", tblsiz );
  1260. X    }
  1261. X
  1262. X#ifndef VMS
  1263. X    exit( status );
  1264. X#else
  1265. X    exit( status + 1 );
  1266. X#endif
  1267. X    }
  1268. X
  1269. X
  1270. X/* flexinit - initialize flex
  1271. X *
  1272. X * synopsis
  1273. X *    int argc;
  1274. X *    char **argv;
  1275. X *    flexinit( argc, argv );
  1276. X */
  1277. X
  1278. Xvoid flexinit( argc, argv )
  1279. Xint argc;
  1280. Xchar **argv;
  1281. X
  1282. X    {
  1283. X    int i, sawcmpflag;
  1284. X    char *arg, *flex_gettime(), *mktemp();
  1285. X
  1286. X    printstats = syntaxerror = trace = spprdflt = interactive = caseins = false;
  1287. X    backtrack_report = performance_report = ddebug = fulltbl = fullspd = false;
  1288. X    yymore_used = continued_action = reject = false;
  1289. X    yymore_really_used = reject_really_used = false;
  1290. X    gen_line_dirs = usemecs = useecs = true;
  1291. X
  1292. X    sawcmpflag = false;
  1293. X    use_stdout = false;
  1294. X
  1295. X    csize = DEFAULT_CSIZE;
  1296. X
  1297. X    program_name = argv[0];
  1298. X
  1299. X    /* read flags */
  1300. X    for ( --argc, ++argv; argc ; --argc, ++argv )
  1301. X    {
  1302. X    if ( argv[0][0] != '-' || argv[0][1] == '\0' )
  1303. X        break;
  1304. X
  1305. X    arg = argv[0];
  1306. X
  1307. X    for ( i = 1; arg[i] != '\0'; ++i )
  1308. X        switch ( arg[i] )
  1309. X        {
  1310. X        case 'b':
  1311. X            backtrack_report = true;
  1312. X            break;
  1313. X
  1314. X        case 'c':
  1315. X            fprintf( stderr,
  1316. X    "%s: Assuming use of deprecated -c flag is really intended to be -C\n",
  1317. X                 program_name );
  1318. X
  1319. X            /* fall through */
  1320. X
  1321. X        case 'C':
  1322. X            if ( i != 1 )
  1323. X            flexerror( "-C flag must be given separately" );
  1324. X
  1325. X            if ( ! sawcmpflag )
  1326. X            {
  1327. X            useecs = false;
  1328. X            usemecs = false;
  1329. X            fulltbl = false;
  1330. X            sawcmpflag = true;
  1331. X            }
  1332. X
  1333. X            for ( ++i; arg[i] != '\0'; ++i )
  1334. X            switch ( arg[i] )
  1335. X                {
  1336. X                case 'e':
  1337. X                useecs = true;
  1338. X                break;
  1339. X
  1340. X                case 'F':
  1341. X                fullspd = true;
  1342. X                break;
  1343. X
  1344. X                case 'f':
  1345. X                fulltbl = true;
  1346. X                break;
  1347. X
  1348. X                case 'm':
  1349. X                usemecs = true;
  1350. X                break;
  1351. X
  1352. X                default:
  1353. X                lerrif( "unknown -C option '%c'",
  1354. X                    (int) arg[i] );
  1355. X                break;
  1356. X                }
  1357. X
  1358. X            goto get_next_arg;
  1359. X
  1360. X        case 'd':
  1361. X            ddebug = true;
  1362. X            break;
  1363. X
  1364. X        case 'f':
  1365. X            useecs = usemecs = false;
  1366. X            fulltbl = true;
  1367. X            break;
  1368. X
  1369. X        case 'F':
  1370. X            useecs = usemecs = false;
  1371. X            fullspd = true;
  1372. X            break;
  1373. X
  1374. X        case 'I':
  1375. X            interactive = true;
  1376. X            break;
  1377. X
  1378. X        case 'i':
  1379. X            caseins = true;
  1380. X            break;
  1381. X
  1382. X        case 'L':
  1383. X            gen_line_dirs = false;
  1384. X            break;
  1385. X
  1386. X        case 'n':
  1387. X            /* stupid do-nothing deprecated option */
  1388. X            break;
  1389. X
  1390. X        case 'p':
  1391. X            performance_report = true;
  1392. X            break;
  1393. X
  1394. X        case 'S':
  1395. X            if ( i != 1 )
  1396. X            flexerror( "-S flag must be given separately" );
  1397. X
  1398. X            skelname = arg + i + 1;
  1399. X            goto get_next_arg;
  1400. X
  1401. X        case 's':
  1402. X            spprdflt = true;
  1403. X            break;
  1404. X
  1405. X        case 't':
  1406. X            use_stdout = true;
  1407. X            break;
  1408. X
  1409. X        case 'T':
  1410. X            trace = true;
  1411. X            break;
  1412. X
  1413. X        case 'v':
  1414. X            printstats = true;
  1415. X            break;
  1416. X
  1417. X        case '8':
  1418. X            csize = CSIZE;
  1419. X            break;
  1420. X
  1421. X        default:
  1422. X            lerrif( "unknown flag '%c'", (int) arg[i] );
  1423. X            break;
  1424. X        }
  1425. X
  1426. Xget_next_arg: /* used by -C and -S flags in lieu of a "continue 2" control */
  1427. X    ;
  1428. X    }
  1429. X
  1430. X    if ( (fulltbl || fullspd) && usemecs )
  1431. X    flexerror( "full table and -Cm don't make sense together" );
  1432. X
  1433. X    if ( (fulltbl || fullspd) && interactive )
  1434. X    flexerror( "full table and -I are (currently) incompatible" );
  1435. X
  1436. X    if ( fulltbl && fullspd )
  1437. X    flexerror( "full table and -F are mutually exclusive" );
  1438. X
  1439. X    if ( ! skelname )
  1440. X    {
  1441. X    static char skeleton_name_storage[400];
  1442. X
  1443. X    skelname = skeleton_name_storage;
  1444. X    (void) strcpy( skelname, DEFAULT_SKELETON_FILE );
  1445. X    }
  1446. X
  1447. X    if ( ! use_stdout )
  1448. X    {
  1449. X    FILE *prev_stdout = freopen( outfile, "w", stdout );
  1450. X
  1451. X    if ( prev_stdout == NULL )
  1452. X        lerrsf( "could not create %s", outfile );
  1453. X
  1454. X    outfile_created = 1;
  1455. X    }
  1456. X
  1457. X    num_input_files = argc;
  1458. X    input_files = argv;
  1459. X    set_input_file( num_input_files > 0 ? input_files[0] : NULL );
  1460. X
  1461. X    if ( backtrack_report )
  1462. X    {
  1463. X#ifndef SHORT_FILE_NAMES
  1464. X    backtrack_file = fopen( "lex.backtrack", "w" );
  1465. X#else
  1466. X    backtrack_file = fopen( "lex.bck", "w" );
  1467. X#endif
  1468. X
  1469. X    if ( backtrack_file == NULL )
  1470. X        flexerror( "could not create lex.backtrack" );
  1471. X    }
  1472. X
  1473. X    else
  1474. X    backtrack_file = NULL;
  1475. X
  1476. X
  1477. X    lastccl = 0;
  1478. X    lastsc = 0;
  1479. X
  1480. X    /* initialize the statistics */
  1481. X    starttime = flex_gettime();
  1482. X
  1483. X    if ( (skelfile = fopen( skelname, "r" )) == NULL )
  1484. X    lerrsf( "can't open skeleton file %s", skelname );
  1485. X
  1486. X#ifdef SYS_V
  1487. X    action_file_name = tmpnam( NULL );
  1488. X#endif
  1489. X
  1490. X    if ( action_file_name == NULL )
  1491. X    {
  1492. X    static char temp_action_file_name[32];
  1493. X
  1494. X#ifdef AMIGA
  1495. X    (void) strcpy( temp_action_file_name, TmpFileName("t:flex") );
  1496. X#else
  1497. X#ifndef SHORT_FILE_NAMES
  1498. X    (void) strcpy( temp_action_file_name, "/tmp/flexXXXXXX" );
  1499. X#else
  1500. X    (void) strcpy( temp_action_file_name, "flexXXXXXX.tmp" );
  1501. X#endif
  1502. X    (void) mktemp( temp_action_file_name );
  1503. X#endif
  1504. X
  1505. X    action_file_name = temp_action_file_name;
  1506. X    }
  1507. X
  1508. X    if ( (temp_action_file = fopen( action_file_name, "w" )) == NULL )
  1509. X    lerrsf( "can't open temporary action file %s", action_file_name );
  1510. X
  1511. X    lastdfa = lastnfa = num_rules = numas = numsnpairs = tmpuses = 0;
  1512. X    numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0;
  1513. X    numuniq = numdup = hshsave = eofseen = datapos = dataline = 0;
  1514. X    num_backtracking = onesp = numprots = 0;
  1515. X    variable_trailing_context_rules = bol_needed = false;
  1516. X
  1517. X    linenum = sectnum = 1;
  1518. X    firstprot = NIL;
  1519. X
  1520. X    /* used in mkprot() so that the first proto goes in slot 1
  1521. X     * of the proto queue
  1522. X     */
  1523. X    lastprot = 1;
  1524. X
  1525. X    if ( useecs )
  1526. X    { /* set up doubly-linked equivalence classes */
  1527. X    /* We loop all the way up to csize, since ecgroup[csize] is the
  1528. X     * position used for NUL characters
  1529. X     */
  1530. X    ecgroup[1] = NIL;
  1531. X
  1532. X    for ( i = 2; i <= csize; ++i )
  1533. X        {
  1534. X        ecgroup[i] = i - 1;
  1535. X        nextecm[i - 1] = i;
  1536. X        }
  1537. X
  1538. X    nextecm[csize] = NIL;
  1539. X    }
  1540. X
  1541. X    else
  1542. X    { /* put everything in its own equivalence class */
  1543. X    for ( i = 1; i <= csize; ++i )
  1544. X        {
  1545. X        ecgroup[i] = i;
  1546. X        nextecm[i] = BAD_SUBSCRIPT;    /* to catch errors */
  1547. X        }
  1548. X    }
  1549. X
  1550. X    set_up_initial_allocations();
  1551. X    }
  1552. X
  1553. X
  1554. X/* readin - read in the rules section of the input file(s)
  1555. X *
  1556. X * synopsis
  1557. X *    readin();
  1558. X */
  1559. X
  1560. Xvoid readin()
  1561. X
  1562. X    {
  1563. X    skelout();
  1564. X
  1565. X    if ( ddebug )
  1566. X    puts( "#define FLEX_DEBUG" );
  1567. X
  1568. X    if ( csize == 256 )
  1569. X    puts( "#define YY_CHAR unsigned char" );
  1570. X    else
  1571. X    puts( "#define YY_CHAR char" );
  1572. X
  1573. X    line_directive_out( stdout );
  1574. X
  1575. X    if ( yyparse() )
  1576. X    {
  1577. X    pinpoint_message( "fatal parse error" );
  1578. X    flexend( 1 );
  1579. X    }
  1580. X
  1581. X    if ( xlation )
  1582. X    {
  1583. X    numecs = ecs_from_xlation( ecgroup );
  1584. X    useecs = true;
  1585. X    }
  1586. X
  1587. X    else if ( useecs )
  1588. X    numecs = cre8ecs( nextecm, ecgroup, csize );
  1589. X
  1590. X    else
  1591. X    numecs = csize;
  1592. X
  1593. X    /* now map the equivalence class for NUL to its expected place */
  1594. X    ecgroup[0] = ecgroup[csize];
  1595. X    NUL_ec = abs( ecgroup[0] );
  1596. X
  1597. X    if ( useecs )
  1598. X    ccl2ecl();
  1599. X    }
  1600. X
  1601. X
  1602. X
  1603. X/* set_up_initial_allocations - allocate memory for internal tables */
  1604. X
  1605. Xvoid set_up_initial_allocations()
  1606. X
  1607. X    {
  1608. X    current_mns = INITIAL_MNS;
  1609. X    firstst = allocate_integer_array( current_mns );
  1610. X    lastst = allocate_integer_array( current_mns );
  1611. X    finalst = allocate_integer_array( current_mns );
  1612. X    transchar = allocate_integer_array( current_mns );
  1613. X    trans1 = allocate_integer_array( current_mns );
  1614. X    trans2 = allocate_integer_array( current_mns );
  1615. X    accptnum = allocate_integer_array( current_mns );
  1616. X    assoc_rule = allocate_integer_array( current_mns );
  1617. X    state_type = allocate_integer_array( current_mns );
  1618. X
  1619. X    current_max_rules = INITIAL_MAX_RULES;
  1620. X    rule_type = allocate_integer_array( current_max_rules );
  1621. X    rule_linenum = allocate_integer_array( current_max_rules );
  1622. X
  1623. X    current_max_scs = INITIAL_MAX_SCS;
  1624. X    scset = allocate_integer_array( current_max_scs );
  1625. X    scbol = allocate_integer_array( current_max_scs );
  1626. X    scxclu = allocate_integer_array( current_max_scs );
  1627. X    sceof = allocate_integer_array( current_max_scs );
  1628. X    scname = allocate_char_ptr_array( current_max_scs );
  1629. X    actvsc = allocate_integer_array( current_max_scs );
  1630. X
  1631. X    current_maxccls = INITIAL_MAX_CCLS;
  1632. X    cclmap = allocate_integer_array( current_maxccls );
  1633. X    ccllen = allocate_integer_array( current_maxccls );
  1634. X    cclng = allocate_integer_array( current_maxccls );
  1635. X
  1636. X    current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE;
  1637. X    ccltbl = allocate_character_array( current_max_ccl_tbl_size );
  1638. X
  1639. X    current_max_dfa_size = INITIAL_MAX_DFA_SIZE;
  1640. X
  1641. X    current_max_xpairs = INITIAL_MAX_XPAIRS;
  1642. X    nxt = allocate_integer_array( current_max_xpairs );
  1643. X    chk = allocate_integer_array( current_max_xpairs );
  1644. X
  1645. X    current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS;
  1646. X    tnxt = allocate_integer_array( current_max_template_xpairs );
  1647. X
  1648. X    current_max_dfas = INITIAL_MAX_DFAS;
  1649. X    base = allocate_integer_array( current_max_dfas );
  1650. X    def = allocate_integer_array( current_max_dfas );
  1651. X    dfasiz = allocate_integer_array( current_max_dfas );
  1652. X    accsiz = allocate_integer_array( current_max_dfas );
  1653. X    dhash = allocate_integer_array( current_max_dfas );
  1654. X    dss = allocate_int_ptr_array( current_max_dfas );
  1655. X    dfaacc = allocate_dfaacc_union( current_max_dfas );
  1656. X
  1657. X    nultrans = (int *) 0;
  1658. X    }
  1659. END_OF_FILE
  1660. if test 20291 -ne `wc -c <'main.c'`; then
  1661.     echo shar: \"'main.c'\" unpacked with wrong size!
  1662. fi
  1663. # end of 'main.c'
  1664. fi
  1665. if test -f 'nfa.c' -a "${1}" != "-c" ; then 
  1666.   echo shar: Will not clobber existing file \"'nfa.c'\"
  1667. else
  1668. echo shar: Extracting \"'nfa.c'\" \(17603 characters\)
  1669. sed "s/^X//" >'nfa.c' <<'END_OF_FILE'
  1670. X/* nfa - NFA construction routines */
  1671. X
  1672. X/*-
  1673. X * Copyright (c) 1990 The Regents of the University of California.
  1674. X * All rights reserved.
  1675. X *
  1676. X * This code is derived from software contributed to Berkeley by
  1677. X * Vern Paxson.
  1678. X * 
  1679. X * The United States Government has rights in this work pursuant
  1680. X * to contract no. DE-AC03-76SF00098 between the United States
  1681. X * Department of Energy and the University of California.
  1682. X *
  1683. X * Redistribution and use in source and binary forms are permitted provided
  1684. X * that: (1) source distributions retain this entire copyright notice and
  1685. X * comment, and (2) distributions including binaries display the following
  1686. X * acknowledgement:  ``This product includes software developed by the
  1687. X * University of California, Berkeley and its contributors'' in the
  1688. X * documentation or other materials provided with the distribution and in
  1689. X * all advertising materials mentioning features or use of this software.
  1690. X * Neither the name of the University nor the names of its contributors may
  1691. X * be used to endorse or promote products derived from this software without
  1692. X * specific prior written permission.
  1693. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  1694. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  1695. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1696. X */
  1697. X
  1698. X#ifndef lint
  1699. Xstatic char rcsid[] =
  1700. X    "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/nfa.c,v 2.6 90/06/27 23:48:29 vern Exp $ (LBL)";
  1701. X#endif
  1702. X
  1703. X#include "flexdef.h"
  1704. X
  1705. X
  1706. X/* declare functions that have forward references */
  1707. X
  1708. Xint dupmachine PROTO((int));
  1709. Xvoid mkxtion PROTO((int, int));
  1710. X
  1711. X
  1712. X/* add_accept - add an accepting state to a machine
  1713. X *
  1714. X * synopsis
  1715. X *
  1716. X *   add_accept( mach, accepting_number );
  1717. X *
  1718. X * accepting_number becomes mach's accepting number.
  1719. X */
  1720. X
  1721. Xvoid add_accept( mach, accepting_number )
  1722. Xint mach, accepting_number;
  1723. X
  1724. X    {
  1725. X    /* hang the accepting number off an epsilon state.  if it is associated
  1726. X     * with a state that has a non-epsilon out-transition, then the state
  1727. X     * will accept BEFORE it makes that transition, i.e., one character
  1728. X     * too soon
  1729. X     */
  1730. X
  1731. X    if ( transchar[finalst[mach]] == SYM_EPSILON )
  1732. X    accptnum[finalst[mach]] = accepting_number;
  1733. X
  1734. X    else
  1735. X    {
  1736. X    int astate = mkstate( SYM_EPSILON );
  1737. X    accptnum[astate] = accepting_number;
  1738. X    mach = link_machines( mach, astate );
  1739. X    }
  1740. X    }
  1741. X
  1742. X
  1743. X/* copysingl - make a given number of copies of a singleton machine
  1744. X *
  1745. X * synopsis
  1746. X *
  1747. X *   newsng = copysingl( singl, num );
  1748. X *
  1749. X *     newsng - a new singleton composed of num copies of singl
  1750. X *     singl  - a singleton machine
  1751. X *     num    - the number of copies of singl to be present in newsng
  1752. X */
  1753. X
  1754. Xint copysingl( singl, num )
  1755. Xint singl, num;
  1756. X
  1757. X    {
  1758. X    int copy, i;
  1759. X
  1760. X    copy = mkstate( SYM_EPSILON );
  1761. X
  1762. X    for ( i = 1; i <= num; ++i )
  1763. X    copy = link_machines( copy, dupmachine( singl ) );
  1764. X
  1765. X    return ( copy );
  1766. X    }
  1767. X
  1768. X
  1769. X/* dumpnfa - debugging routine to write out an nfa
  1770. X *
  1771. X * synopsis
  1772. X *    int state1;
  1773. X *    dumpnfa( state1 );
  1774. X */
  1775. X
  1776. Xvoid dumpnfa( state1 )
  1777. Xint state1;
  1778. X
  1779. X    {
  1780. X    int sym, tsp1, tsp2, anum, ns;
  1781. X
  1782. X    fprintf( stderr, "\n\n********** beginning dump of nfa with start state %d\n",
  1783. X         state1 );
  1784. X
  1785. X    /* we probably should loop starting at firstst[state1] and going to
  1786. X     * lastst[state1], but they're not maintained properly when we "or"
  1787. X     * all of the rules together.  So we use our knowledge that the machine
  1788. X     * starts at state 1 and ends at lastnfa.
  1789. X     */
  1790. X
  1791. X    /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */
  1792. X    for ( ns = 1; ns <= lastnfa; ++ns )
  1793. X    {
  1794. X    fprintf( stderr, "state # %4d\t", ns );
  1795. X
  1796. X    sym = transchar[ns];
  1797. X    tsp1 = trans1[ns];
  1798. X    tsp2 = trans2[ns];
  1799. X    anum = accptnum[ns];
  1800. X
  1801. X    fprintf( stderr, "%3d:  %4d, %4d", sym, tsp1, tsp2 );
  1802. X
  1803. X    if ( anum != NIL )
  1804. X        fprintf( stderr, "  [%d]", anum );
  1805. X
  1806. X    fprintf( stderr, "\n" );
  1807. X    }
  1808. X
  1809. X    fprintf( stderr, "********** end of dump\n" );
  1810. X    }
  1811. X
  1812. X
  1813. X/* dupmachine - make a duplicate of a given machine
  1814. X *
  1815. X * synopsis
  1816. X *
  1817. X *   copy = dupmachine( mach );
  1818. X *
  1819. X *     copy - holds duplicate of mach
  1820. X *     mach - machine to be duplicated
  1821. X *
  1822. X * note that the copy of mach is NOT an exact duplicate; rather, all the
  1823. X * transition states values are adjusted so that the copy is self-contained,
  1824. X * as the original should have been.
  1825. X *
  1826. X * also note that the original MUST be contiguous, with its low and high
  1827. X * states accessible by the arrays firstst and lastst
  1828. X */
  1829. X
  1830. Xint dupmachine( mach )
  1831. Xint mach;
  1832. X
  1833. X    {
  1834. X    int i, init, state_offset;
  1835. X    int state = 0;
  1836. X    int last = lastst[mach];
  1837. X
  1838. X    for ( i = firstst[mach]; i <= last; ++i )
  1839. X    {
  1840. X    state = mkstate( transchar[i] );
  1841. X
  1842. X    if ( trans1[i] != NO_TRANSITION )
  1843. X        {
  1844. X        mkxtion( finalst[state], trans1[i] + state - i );
  1845. X
  1846. X        if ( transchar[i] == SYM_EPSILON && trans2[i] != NO_TRANSITION )
  1847. X        mkxtion( finalst[state], trans2[i] + state - i );
  1848. X        }
  1849. X
  1850. X    accptnum[state] = accptnum[i];
  1851. X    }
  1852. X
  1853. X    if ( state == 0 )
  1854. X    flexfatal( "empty machine in dupmachine()" );
  1855. X
  1856. X    state_offset = state - i + 1;
  1857. X
  1858. X    init = mach + state_offset;
  1859. X    firstst[init] = firstst[mach] + state_offset;
  1860. X    finalst[init] = finalst[mach] + state_offset;
  1861. X    lastst[init] = lastst[mach] + state_offset;
  1862. X
  1863. X    return ( init );
  1864. X    }
  1865. X
  1866. X
  1867. X/* finish_rule - finish up the processing for a rule
  1868. X *
  1869. X * synopsis
  1870. X *
  1871. X *   finish_rule( mach, variable_trail_rule, headcnt, trailcnt );
  1872. X *
  1873. X * An accepting number is added to the given machine.  If variable_trail_rule
  1874. X * is true then the rule has trailing context and both the head and trail
  1875. X * are variable size.  Otherwise if headcnt or trailcnt is non-zero then
  1876. X * the machine recognizes a pattern with trailing context and headcnt is
  1877. X * the number of characters in the matched part of the pattern, or zero
  1878. X * if the matched part has variable length.  trailcnt is the number of
  1879. X * trailing context characters in the pattern, or zero if the trailing
  1880. X * context has variable length.
  1881. X */
  1882. X
  1883. Xvoid finish_rule( mach, variable_trail_rule, headcnt, trailcnt )
  1884. Xint mach, variable_trail_rule, headcnt, trailcnt;
  1885. X
  1886. X    {
  1887. X    add_accept( mach, num_rules );
  1888. X
  1889. X    /* we did this in new_rule(), but it often gets the wrong
  1890. X     * number because we do it before we start parsing the current rule
  1891. X     */
  1892. X    rule_linenum[num_rules] = linenum;
  1893. X
  1894. X    /* if this is a continued action, then the line-number has
  1895. X     * already been updated, giving us the wrong number
  1896. X     */
  1897. X    if ( continued_action )
  1898. X    --rule_linenum[num_rules];
  1899. X
  1900. X    fprintf( temp_action_file, "case %d:\n", num_rules );
  1901. X
  1902. X    if ( variable_trail_rule )
  1903. X    {
  1904. X    rule_type[num_rules] = RULE_VARIABLE;
  1905. X
  1906. X    if ( performance_report )
  1907. X        fprintf( stderr, "Variable trailing context rule at line %d\n",
  1908. X             rule_linenum[num_rules] );
  1909. X
  1910. X    variable_trailing_context_rules = true;
  1911. X    }
  1912. X
  1913. X    else
  1914. X    {
  1915. X    rule_type[num_rules] = RULE_NORMAL;
  1916. X
  1917. X    if ( headcnt > 0 || trailcnt > 0 )
  1918. X        {
  1919. X        /* do trailing context magic to not match the trailing characters */
  1920. X        char *scanner_cp = "yy_c_buf_p = yy_cp";
  1921. X        char *scanner_bp = "yy_bp";
  1922. X
  1923. X        fprintf( temp_action_file,
  1924. X    "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" );
  1925. X
  1926. X        if ( headcnt > 0 )
  1927. X        fprintf( temp_action_file, "%s = %s + %d;\n",
  1928. X             scanner_cp, scanner_bp, headcnt );
  1929. X
  1930. X        else
  1931. X        fprintf( temp_action_file,
  1932. X             "%s -= %d;\n", scanner_cp, trailcnt );
  1933. X    
  1934. X        fprintf( temp_action_file,
  1935. X             "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" );
  1936. X        }
  1937. X    }
  1938. X
  1939. X    line_directive_out( temp_action_file );
  1940. X    }
  1941. X
  1942. X
  1943. X/* link_machines - connect two machines together
  1944. X *
  1945. X * synopsis
  1946. X *
  1947. X *   new = link_machines( first, last );
  1948. X *
  1949. X *     new    - a machine constructed by connecting first to last
  1950. X *     first  - the machine whose successor is to be last
  1951. X *     last   - the machine whose predecessor is to be first
  1952. X *
  1953. X * note: this routine concatenates the machine first with the machine
  1954. X *  last to produce a machine new which will pattern-match first first
  1955. X *  and then last, and will fail if either of the sub-patterns fails.
  1956. X *  FIRST is set to new by the operation.  last is unmolested.
  1957. X */
  1958. X
  1959. Xint link_machines( first, last )
  1960. Xint first, last;
  1961. X
  1962. X    {
  1963. X    if ( first == NIL )
  1964. X    return ( last );
  1965. X
  1966. X    else if ( last == NIL )
  1967. X    return ( first );
  1968. X
  1969. X    else
  1970. X    {
  1971. X    mkxtion( finalst[first], last );
  1972. X    finalst[first] = finalst[last];
  1973. X    lastst[first] = max( lastst[first], lastst[last] );
  1974. X    firstst[first] = min( firstst[first], firstst[last] );
  1975. X
  1976. X    return ( first );
  1977. X    }
  1978. X    }
  1979. X
  1980. X
  1981. X/* mark_beginning_as_normal - mark each "beginning" state in a machine
  1982. X *                            as being a "normal" (i.e., not trailing context-
  1983. X *                            associated) states
  1984. X *
  1985. X * synopsis
  1986. X *
  1987. X *   mark_beginning_as_normal( mach )
  1988. X *
  1989. X *     mach - machine to mark
  1990. X *
  1991. X * The "beginning" states are the epsilon closure of the first state
  1992. X */
  1993. X
  1994. Xvoid mark_beginning_as_normal( mach )
  1995. Xregister int mach;
  1996. X
  1997. X    {
  1998. X    switch ( state_type[mach] )
  1999. X    {
  2000. X    case STATE_NORMAL:
  2001. X        /* oh, we've already visited here */
  2002. X        return;
  2003. X
  2004. X    case STATE_TRAILING_CONTEXT:
  2005. X        state_type[mach] = STATE_NORMAL;
  2006. X
  2007. X        if ( transchar[mach] == SYM_EPSILON )
  2008. X        {
  2009. X        if ( trans1[mach] != NO_TRANSITION )
  2010. X            mark_beginning_as_normal( trans1[mach] );
  2011. X
  2012. X        if ( trans2[mach] != NO_TRANSITION )
  2013. X            mark_beginning_as_normal( trans2[mach] );
  2014. X        }
  2015. X        break;
  2016. X
  2017. X    default:
  2018. X        flexerror( "bad state type in mark_beginning_as_normal()" );
  2019. X        break;
  2020. X    }
  2021. X    }
  2022. X
  2023. X
  2024. X/* mkbranch - make a machine that branches to two machines
  2025. X *
  2026. X * synopsis
  2027. X *
  2028. X *   branch = mkbranch( first, second );
  2029. X *
  2030. X *     branch - a machine which matches either first's pattern or second's
  2031. X *     first, second - machines whose patterns are to be or'ed (the | operator)
  2032. X *
  2033. X * note that first and second are NEITHER destroyed by the operation.  Also,
  2034. X * the resulting machine CANNOT be used with any other "mk" operation except
  2035. X * more mkbranch's.  Compare with mkor()
  2036. X */
  2037. X
  2038. Xint mkbranch( first, second )
  2039. Xint first, second;
  2040. X
  2041. X    {
  2042. X    int eps;
  2043. X
  2044. X    if ( first == NO_TRANSITION )
  2045. X    return ( second );
  2046. X
  2047. X    else if ( second == NO_TRANSITION )
  2048. X    return ( first );
  2049. X
  2050. X    eps = mkstate( SYM_EPSILON );
  2051. X
  2052. X    mkxtion( eps, first );
  2053. X    mkxtion( eps, second );
  2054. X
  2055. X    return ( eps );
  2056. X    }
  2057. X
  2058. X
  2059. X/* mkclos - convert a machine into a closure
  2060. X *
  2061. X * synopsis
  2062. X *   new = mkclos( state );
  2063. X *
  2064. X *     new - a new state which matches the closure of "state"
  2065. X */
  2066. X
  2067. Xint mkclos( state )
  2068. Xint state;
  2069. X
  2070. X    {
  2071. X    return ( mkopt( mkposcl( state ) ) );
  2072. X    }
  2073. X
  2074. X
  2075. X/* mkopt - make a machine optional
  2076. X *
  2077. X * synopsis
  2078. X *
  2079. X *   new = mkopt( mach );
  2080. X *
  2081. X *     new  - a machine which optionally matches whatever mach matched
  2082. X *     mach - the machine to make optional
  2083. X *
  2084. X * notes:
  2085. X *     1. mach must be the last machine created
  2086. X *     2. mach is destroyed by the call
  2087. X */
  2088. X
  2089. Xint mkopt( mach )
  2090. Xint mach;
  2091. X
  2092. X    {
  2093. X    int eps;
  2094. X
  2095. X    if ( ! SUPER_FREE_EPSILON(finalst[mach]) )
  2096. X    {
  2097. X    eps = mkstate( SYM_EPSILON );
  2098. X    mach = link_machines( mach, eps );
  2099. X    }
  2100. X
  2101. X    /* can't skimp on the following if FREE_EPSILON(mach) is true because
  2102. X     * some state interior to "mach" might point back to the beginning
  2103. X     * for a closure
  2104. X     */
  2105. X    eps = mkstate( SYM_EPSILON );
  2106. X    mach = link_machines( eps, mach );
  2107. X
  2108. X    mkxtion( mach, finalst[mach] );
  2109. X
  2110. X    return ( mach );
  2111. X    }
  2112. X
  2113. X
  2114. X/* mkor - make a machine that matches either one of two machines
  2115. X *
  2116. X * synopsis
  2117. X *
  2118. X *   new = mkor( first, second );
  2119. X *
  2120. X *     new - a machine which matches either first's pattern or second's
  2121. X *     first, second - machines whose patterns are to be or'ed (the | operator)
  2122. X *
  2123. X * note that first and second are both destroyed by the operation
  2124. X * the code is rather convoluted because an attempt is made to minimize
  2125. X * the number of epsilon states needed
  2126. X */
  2127. X
  2128. Xint mkor( first, second )
  2129. Xint first, second;
  2130. X
  2131. X    {
  2132. X    int eps, orend;
  2133. X
  2134. X    if ( first == NIL )
  2135. X    return ( second );
  2136. X
  2137. X    else if ( second == NIL )
  2138. X    return ( first );
  2139. X
  2140. X    else
  2141. X    {
  2142. X    /* see comment in mkopt() about why we can't use the first state
  2143. X     * of "first" or "second" if they satisfy "FREE_EPSILON"
  2144. X     */
  2145. X    eps = mkstate( SYM_EPSILON );
  2146. X
  2147. X    first = link_machines( eps, first );
  2148. X
  2149. X    mkxtion( first, second );
  2150. X
  2151. X    if ( SUPER_FREE_EPSILON(finalst[first]) &&
  2152. X         accptnum[finalst[first]] == NIL )
  2153. X        {
  2154. X        orend = finalst[first];
  2155. X        mkxtion( finalst[second], orend );
  2156. X        }
  2157. X
  2158. X    else if ( SUPER_FREE_EPSILON(finalst[second]) &&
  2159. X          accptnum[finalst[second]] == NIL )
  2160. X        {
  2161. X        orend = finalst[second];
  2162. X        mkxtion( finalst[first], orend );
  2163. X        }
  2164. X
  2165. X    else
  2166. X        {
  2167. X        eps = mkstate( SYM_EPSILON );
  2168. X
  2169. X        first = link_machines( first, eps );
  2170. X        orend = finalst[first];
  2171. X
  2172. X        mkxtion( finalst[second], orend );
  2173. X        }
  2174. X    }
  2175. X
  2176. X    finalst[first] = orend;
  2177. X    return ( first );
  2178. X    }
  2179. X
  2180. X
  2181. X/* mkposcl - convert a machine into a positive closure
  2182. X *
  2183. X * synopsis
  2184. X *   new = mkposcl( state );
  2185. X *
  2186. X *    new - a machine matching the positive closure of "state"
  2187. X */
  2188. X
  2189. Xint mkposcl( state )
  2190. Xint state;
  2191. X
  2192. X    {
  2193. X    int eps;
  2194. X
  2195. X    if ( SUPER_FREE_EPSILON(finalst[state]) )
  2196. X    {
  2197. X    mkxtion( finalst[state], state );
  2198. X    return ( state );
  2199. X    }
  2200. X
  2201. X    else
  2202. X    {
  2203. X    eps = mkstate( SYM_EPSILON );
  2204. X    mkxtion( eps, state );
  2205. X    return ( link_machines( state, eps ) );
  2206. X    }
  2207. X    }
  2208. X
  2209. X
  2210. X/* mkrep - make a replicated machine
  2211. X *
  2212. X * synopsis
  2213. X *   new = mkrep( mach, lb, ub );
  2214. X *
  2215. X *    new - a machine that matches whatever "mach" matched from "lb"
  2216. X *          number of times to "ub" number of times
  2217. X *
  2218. X * note
  2219. X *   if "ub" is INFINITY then "new" matches "lb" or more occurrences of "mach"
  2220. X */
  2221. X
  2222. Xint mkrep( mach, lb, ub )
  2223. Xint mach, lb, ub;
  2224. X
  2225. X    {
  2226. X    int base_mach, tail, copy, i;
  2227. X
  2228. X    base_mach = copysingl( mach, lb - 1 );
  2229. X
  2230. X    if ( ub == INFINITY )
  2231. X    {
  2232. X    copy = dupmachine( mach );
  2233. X    mach = link_machines( mach,
  2234. X                  link_machines( base_mach, mkclos( copy ) ) );
  2235. X    }
  2236. X
  2237. X    else
  2238. X    {
  2239. X    tail = mkstate( SYM_EPSILON );
  2240. X
  2241. X    for ( i = lb; i < ub; ++i )
  2242. X        {
  2243. X        copy = dupmachine( mach );
  2244. X        tail = mkopt( link_machines( copy, tail ) );
  2245. X        }
  2246. X
  2247. X    mach = link_machines( mach, link_machines( base_mach, tail ) );
  2248. X    }
  2249. X
  2250. X    return ( mach );
  2251. X    }
  2252. X
  2253. X
  2254. X/* mkstate - create a state with a transition on a given symbol
  2255. X *
  2256. X * synopsis
  2257. X *
  2258. X *   state = mkstate( sym );
  2259. X *
  2260. X *     state - a new state matching sym
  2261. X *     sym   - the symbol the new state is to have an out-transition on
  2262. X *
  2263. X * note that this routine makes new states in ascending order through the
  2264. X * state array (and increments LASTNFA accordingly).  The routine DUPMACHINE
  2265. X * relies on machines being made in ascending order and that they are
  2266. X * CONTIGUOUS.  Change it and you will have to rewrite DUPMACHINE (kludge
  2267. X * that it admittedly is)
  2268. X */
  2269. X
  2270. Xint mkstate( sym )
  2271. Xint sym;
  2272. X
  2273. X    {
  2274. X    if ( ++lastnfa >= current_mns )
  2275. X    {
  2276. X    if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS )
  2277. X        lerrif( "input rules are too complicated (>= %d NFA states)",
  2278. X            current_mns );
  2279. X    
  2280. X    ++num_reallocs;
  2281. X
  2282. X    firstst = reallocate_integer_array( firstst, current_mns );
  2283. X    lastst = reallocate_integer_array( lastst, current_mns );
  2284. X    finalst = reallocate_integer_array( finalst, current_mns );
  2285. X    transchar = reallocate_integer_array( transchar, current_mns );
  2286. X    trans1 = reallocate_integer_array( trans1, current_mns );
  2287. X    trans2 = reallocate_integer_array( trans2, current_mns );
  2288. X    accptnum = reallocate_integer_array( accptnum, current_mns );
  2289. X    assoc_rule = reallocate_integer_array( assoc_rule, current_mns );
  2290. X    state_type = reallocate_integer_array( state_type, current_mns );
  2291. X    }
  2292. X
  2293. X    firstst[lastnfa] = lastnfa;
  2294. X    finalst[lastnfa] = lastnfa;
  2295. X    lastst[lastnfa] = lastnfa;
  2296. X    transchar[lastnfa] = sym;
  2297. X    trans1[lastnfa] = NO_TRANSITION;
  2298. X    trans2[lastnfa] = NO_TRANSITION;
  2299. X    accptnum[lastnfa] = NIL;
  2300. X    assoc_rule[lastnfa] = num_rules;
  2301. X    state_type[lastnfa] = current_state_type;
  2302. X
  2303. X    /* fix up equivalence classes base on this transition.  Note that any
  2304. X     * character which has its own transition gets its own equivalence class.
  2305. X     * Thus only characters which are only in character classes have a chance
  2306. X     * at being in the same equivalence class.  E.g. "a|b" puts 'a' and 'b'
  2307. X     * into two different equivalence classes.  "[ab]" puts them in the same
  2308. X     * equivalence class (barring other differences elsewhere in the input).
  2309. X     */
  2310. X
  2311. X    if ( sym < 0 )
  2312. X    {
  2313. X    /* we don't have to update the equivalence classes since that was
  2314. X     * already done when the ccl was created for the first time
  2315. X     */
  2316. X    }
  2317. X
  2318. X    else if ( sym == SYM_EPSILON )
  2319. X    ++numeps;
  2320. X
  2321. X    else
  2322. X    {
  2323. X    if ( useecs )
  2324. X        /* map NUL's to csize */
  2325. X        mkechar( sym ? sym : csize, nextecm, ecgroup );
  2326. X    }
  2327. X
  2328. X    return ( lastnfa );
  2329. X    }
  2330. X
  2331. X
  2332. X/* mkxtion - make a transition from one state to another
  2333. X *
  2334. X * synopsis
  2335. X *
  2336. X *   mkxtion( statefrom, stateto );
  2337. X *
  2338. X *     statefrom - the state from which the transition is to be made
  2339. X *     stateto   - the state to which the transition is to be made
  2340. X */
  2341. X
  2342. Xvoid mkxtion( statefrom, stateto )
  2343. Xint statefrom, stateto;
  2344. X
  2345. X    {
  2346. X    if ( trans1[statefrom] == NO_TRANSITION )
  2347. X    trans1[statefrom] = stateto;
  2348. X
  2349. X    else if ( (transchar[statefrom] != SYM_EPSILON) ||
  2350. X          (trans2[statefrom] != NO_TRANSITION) )
  2351. X    flexfatal( "found too many transitions in mkxtion()" );
  2352. X
  2353. X    else
  2354. X    { /* second out-transition for an epsilon state */
  2355. X    ++eps2;
  2356. X    trans2[statefrom] = stateto;
  2357. X    }
  2358. X    }
  2359. X
  2360. X/* new_rule - initialize for a new rule
  2361. X *
  2362. X * synopsis
  2363. X *
  2364. X *   new_rule();
  2365. X *
  2366. X * the global num_rules is incremented and the any corresponding dynamic
  2367. X * arrays (such as rule_type[]) are grown as needed.
  2368. X */
  2369. X
  2370. Xvoid new_rule()
  2371. X
  2372. X    {
  2373. X    if ( ++num_rules >= current_max_rules )
  2374. X    {
  2375. X    ++num_reallocs;
  2376. X    current_max_rules += MAX_RULES_INCREMENT;
  2377. X    rule_type = reallocate_integer_array( rule_type, current_max_rules );
  2378. X    rule_linenum =
  2379. X        reallocate_integer_array( rule_linenum, current_max_rules );
  2380. X    }
  2381. X
  2382. X    if ( num_rules > MAX_RULE )
  2383. X    lerrif( "too many rules (> %d)!", MAX_RULE );
  2384. X
  2385. X    rule_linenum[num_rules] = linenum;
  2386. X    }
  2387. END_OF_FILE
  2388. if test 17603 -ne `wc -c <'nfa.c'`; then
  2389.     echo shar: \"'nfa.c'\" unpacked with wrong size!
  2390. fi
  2391. # end of 'nfa.c'
  2392. fi
  2393. echo shar: End of archive 3 \(of 13\).
  2394. cp /dev/null ark3isdone
  2395. MISSING=""
  2396. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  2397.     if test ! -f ark${I}isdone ; then
  2398.     MISSING="${MISSING} ${I}"
  2399.     fi
  2400. done
  2401. if test "${MISSING}" = "" ; then
  2402.     echo You have unpacked all 13 archives.
  2403.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2404. else
  2405.     echo You still need to unpack the following archives:
  2406.     echo "        " ${MISSING}
  2407. fi
  2408. ##  End of shell archive.
  2409. exit 0
  2410. -- 
  2411. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2412. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2413. Post requests for sources, and general discussion to comp.sys.amiga.
  2414.